#include "Disk.h"

bool Disk::intersect(const Ray &ray, IntersectResult &result) const {
	Double a = ray.dir * normal;
	if (ISZERO(a)) return false;
	bool inHit = a < 0;
	if (!doubleSide && !inHit) return false;
	Vector3 po = position - ray.origin;
	Double d = (po * normal) / a;
	if (d <= EPS) return false;
	Vector3 p = ray.getPoint(d);
	Vector3 r = position - p;
	if (r.lengthSqr() >= radiusSqr) return false;
	result.primitive = this;
	result.distance = d;
	result.position = p;
	result.normal = (inHit) ? normal : -normal;
	return true;
}

bool Disk::intersectP(const Ray & ray) const {
	Double a = ray.dir * normal;
	bool inHit = a < 0;
	if (!inHit && a < EPS) return false;
	if (!doubleSide && !inHit) return false;
	Vector3 po = position - ray.origin;
	Double d = (po * normal) / a;
	if (d <= EPS) return false;
	Vector3 p = ray.getPoint(d);
	Vector3 r = position - p;
	if (r.lengthSqr() >= radiusSqr) return false;
	return true;
}

string Disk::str() const {
	std::ostringstream s;
	s << getName() << "(pos = " << position.str() << ", normal = " << normal.str() << ", r = " << radius << ")";
	return s.str();
}